package br.com.taskManager.dao.imp;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;

import br.com.taskManager.dao.DaoGenerico;

public abstract class DaoGenericoImp<T, ID extends Serializable> implements DaoGenerico<T, ID> {

	@Autowired
	private HibernateTemplate hibernateTemplate;

	private final Class<T> oClass;

	@SuppressWarnings("unchecked")
	public DaoGenericoImp() {
		this.oClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}

	@Override
	public Class<T> getObjectClass() {
		return this.oClass;
	}

	@Override
	public void save(T entity) {
		try {
			getHibernateTemplate().save(entity);
		} catch (DataAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (HibernateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public T getById(Serializable id) {
		return getHibernateTemplate().get(this.oClass, id);
	}

	@Override
	public void update(T entity) {
		getHibernateTemplate().update(entity);
	}

	@Override
	public void delete(T entity) {
		entity = getHibernateTemplate().merge(entity);
		getHibernateTemplate().delete(entity);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> getList() {
		List<T> lista;
		Criteria criteria = getHibernateTemplate().getSessionFactory().getCurrentSession().createCriteria(this.oClass);
		lista = criteria.list();
		return lista;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> getListPesqParam(String query, Map<String, Object> params) {
		Query q = getHibernateTemplate().getSessionFactory().getCurrentSession().createQuery(query);
		for (String chave : params.keySet()) {
			q.setParameter(chave, params.get(chave));
		}
		return q.list();
	}

	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}

	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

}
